<?php
require_once('simpletest/autorun.php');
require_once('../templar.php');
require_once('templar_testing_resources.php');


/**********************************************************************
 * Test of successful TemplarPHP instantiation.
 *********************************************************************/
class TestInstantiation extends TemplarUnitTestCase {
    function testInstantiateMainClass() {
        $templar = new TemplarPHP();
        $this->assertNotNull($templar);
    }
}

/**********************************************************************
 * Check client and server environment detection.
 *********************************************************************/
class TestClientAndServerEnvironment extends TemplarUnitTestCase {
    function testClientEnvironment() {
        $templar = new TemplarPHP();
        $this->assertEqual($templar->envRemoteAddr, $this->testEnv['REMOTE_ADDR']);
        $this->assertEqual($templar->envUserAgent, $this->testEnv['HTTP_USER_AGENT']);
    }
    function testServerEnvironment() {
        $templar = new TemplarPHP();
        if ($_SERVER['HTTPS'] == 'on') {
            $this->assertEqual($templar->envScheme, 'https');
        } else {
            $this->assertEqual($templar->envScheme, 'http');
        }
        $this->assertEqual($templar->envHost, $this->testEnv['HTTP_HOST']);
    }
}

/**********************************************************************
 * Check TemplarPHP's internal handling of Web and file root paths.
 *********************************************************************/
class TestScriptEnvironment extends TemplarUnitTestCase {
    protected $dummyFilePath   = 'dummy_controller.php';
    protected $dummyScriptName = NULL; // gets script name equivalent
    function setUp() {
        TemplarUnitTestCase::setUp(); // <- always call last!
        file_put_contents($this->dummyFilePath, 'dummy file contents'); // create dummy file
        $this->dummyScriptName = dirname(getenv('SCRIPT_NAME')) . '/' . $this->dummyFilePath;
        $_SERVER['SCRIPT_NAME'] = $this->dummyScriptName;
    }
    function tearDown() {
        $_SERVER['SCRIPT_NAME'] = getenv('SCRIPT_NAME');
        @unlink($this->dummyFilePath); // remove dummy file
        TemplarUnitTestCase::tearDown(); // <- always call first!
    }
    /* test of server environment detection */
    function testWebRootAndFileRoot() {
        $templar = new TemplarPHP();
        $this->assertEqual($templar->envScript, $this->dummyScriptName);
        // default web root gets envScript's folder
        $web_root = dirname($this->dummyScriptName) . '/';
        $this->assertEqual($templar->envWebRoot, $web_root);
        // default file root ends with envScript's folder
        $file_root_pat = $web_root . 'temp/'; // constructor should set path to temp/
        $file_root_pat = str_replace('/', '\/', $file_root_pat); // escape slashes
        $file_root_pat = '/' . $file_root_pat . '$/';       // complete regex pat
        $this->assertPattern($file_root_pat, $templar->envFileRoot);
    }
}

/**********************************************************************
 * Verify relative request handling (relative to web root).
 *********************************************************************/
class TestRelativeRequestHandling extends TemplarUnitTestCase {

    function testSimpleMatchingRequests() {
        $templar = createProxyClass('TemplarPHP');
        //$templar = new TemplarPHP();
        $templar->envWebRoot = '/dummy_web_root/';

        $request = '/dummy_web_root/dummy_file.txt';
        $result = $templar->formatRequest($request);
        $this->assertEqual($result, 'dummy_file.txt');

        $request = '/dummy_web_root/dummy_file';
        $result = $templar->formatRequest($request);
        $this->assertEqual($result, 'dummy_file');

        $request = '/dummy_web_root/sub_dir/dummy_file';
        $result = $templar->formatRequest($request);
        $this->assertEqual($result, 'sub_dir/dummy_file');
    }

    function testNonMatchingRequests() {
        $templar = createProxyClass('TemplarPHP');
        $templar->envWebRoot = '/dummy_web_root/';

        /* relative (no leading slash) */
        $request = 'dummy_web_root/dummy_file';
        $result = $templar->formatRequest($request);
        $this->assertEqual($result, 'dummy_web_root/dummy_file');

        /* relative (no leading slash) */
        $request = 'dummy_file'; // no matching root (treated as relative)
        $result = $templar->formatRequest($request);
        $this->assertEqual($result, 'dummy_file');

        /* leading slash, but doesn't match web root (treated as relative) */
        $request = '/dummy_file';
        $result = $templar->formatRequest($request);
        $this->assertEqual($result, 'dummy_file');

        /* leading slash, but doesn't match web root (treated as relative) */
        $request = '/some_other_root/dummy_file';
        $result = $templar->formatRequest($request);
        $this->assertEqual($result, 'some_other_root/dummy_file');
    }

    function testTrailingSlashRequest() {
        $templar = createProxyClass('TemplarPHP');
        $templar->envWebRoot = '/dummy_web_root/';

        $request = ''; // empty request treated as root index request
        $result = $templar->formatRequest($request);
        $this->assertEqual($result, 'index');

        $request = '/'; // root index request
        $result = $templar->formatRequest($request);
        $this->assertEqual($result, 'index');

        $request = '/dummy_web_root/temp/'; // matches web root
        $result = $templar->formatRequest($request);
        $this->assertEqual($result, 'temp/index');

        $request = 'dummy_web_root/'; // non-match index request
        $result = $templar->formatRequest($request);
        $this->assertEqual($result, 'dummy_web_root/index');
    }

    // TODO: ADD TESTS FOR NON-DEFAULT DIRECTORY SETUPS?
}


/**********************************************************************
 * Check logging functionality at different logging levels.
 *********************************************************************/
class TestLoggingService extends TemplarUnitTestCase {
    function testDefaultLogging() {
        $templar = new TemplarPHP();
        $templar->logLevel = 2;
        $templar->log(1, 'A');
        $templar->log(2, 'B');
        $templar->log(3, 'C');
        $this->assertEqual($templar->eventLog, array('A','B'));
    }
    function testNoLogging() {
        $templar = new TemplarPHP();
        $templar->logLevel = 0;
        $templar->log(1, 'A');
        $templar->log(2, 'B');
        $templar->log(3, 'C');
        $this->assertIdentical($templar->eventLog, array());
    }
}


/**********************************************************************
 * Test public registerResponseStatus() & protected responseStatus.
 *********************************************************************/
class TestResponseStatus extends TemplarUnitTestCase {
    function testResponseStatusRegistration() {
        $templar = createProxyClass('TemplarPHP');
        $this->assertNull($templar->responseStatus);
        $templar->registerStatusCode('404 Not Found');
        $this->assertEqual($templar->responseStatus, '404 Not Found');
    }
    function testResponseStatusLogging() {
        $templar = createProxyClass('TemplarPHP');
        $this->assertEqual(count($templar->eventLog), 0);
        $templar->registerStatusCode('404 Not Found');
        $this->assertEqual(count($templar->eventLog), 1);
    }
}

class TestRegisterHeader extends TemplarUnitTestCase {
    function testSetHeaders() {
        $templar = $this->templar;
        $this->assertIdentical($templar->responseHeaders, array());

        $templar->registerHeader('Last-Modified', 'Dummy Date');
        $templar->registerHeader('ETag', 'Dummy ETag');

        $result_array = array(
            'Last-Modified' => 'Dummy Date',
            'ETag' => 'Dummy ETag'
        );
        $this->assertEqual($templar->responseHeaders, $result_array);
        // TODO: Add general logging check.
    }
    function testReplaceHeader() {
        $templar = $this->templar;
        $this->assertIdentical($templar->responseHeaders, array());

        $templar->registerHeader('Last-Modified', 'Dummy Date');
        $this->assertEqual($templar->responseHeaders['Last-Modified'], 'Dummy Date');

        $templar->registerHeader('Last-Modified', 'Replaced');
        $this->assertEqual($templar->responseHeaders['Last-Modified'], 'Replaced');
        // TODO: Add check for replacement notice in log.
    }
}



/**********************************************************************
 *
 *********************************************************************/
class TestGetLastModified extends TemplarUnitTestCase {
    function setUp() {
        TemplarUnitTestCase::setUp();
        file_put_contents('a.html', '');
        file_put_contents('b.html', '');
        file_put_contents('c.html', '');
        touch('a.html', 1001116800); // 2001 Sep 22
        touch('b.html', 1255542069); // 2009 Oct 14
        touch('c.html',  946684800); // 2000 Jan 01
    }
    function tearDown() {
        @unlink('a.html');
        @unlink('b.html');
        @unlink('c.html');
        TemplarUnitTestCase::tearDown();
    }
    function testBasicTest() {
        $arr = array('a.html', 'b.html', 'c.html');
        $last_modified = $this->templar->getLastModified($arr);
        $this->assertIdentical($last_modified, 1255542069);
    }
}

class TestETagHash extends TemplarUnitTestCase {
    function setUp() {
        TemplarUnitTestCase::setUp();
        file_put_contents('etag_hash_test.php', '<?php $x = 1; ?>');
    }
    function tearDown() {
        @unlink('etag_hash_test.php');
        TemplarUnitTestCase::tearDown();
    }
    function testEtagHashGeneration() {
        $hash_one = $this->templar->controllerScriptHash();
        include_once('etag_hash_test.php');
        $hash_two = $this->templar->controllerScriptHash();

        $md5_pat = '/[\da-fA-F]{32}/';
        $this->assertPattern($md5_pat, $hash_one);
        $this->assertPattern($md5_pat, $hash_two);
        $this->assertNotEqual($hash_one, $hash_two);
    }
}


/**********************************************************************
 * This is an integration test...
 *********************************************************************/
/*
class TestPrepareResponse extends TemplarUnitTestCase {
    function setUp() {
        TemplarUnitTestCase::setUp();
        file_put_contents('content.html', '<html><head><title></title></head><body><h1>Prepare Response</h1></body></html>');
    }
    function tearDown() {
        @unlink('content.html');
        TemplarUnitTestCase::tearDown();
    }
    function testBasic() {
        //$templar = $this->templar;
        $templar = new TemplarPHP(); // don't use proxy
        $templar->prepareResponse('/content');
        echo $templar->dom;
    }
}
*/



/**********************************************************************
 *
 *********************************************************************/
/*
class TestPrepareResponse extends TemplarUnitTestCase {
    function setUp() {
        TemplarUnitTestCase::setUp();
        file_put_contents('file_a.html', ''); // create dummy file
    }
    function tearDown() {
        @unlink('file_a.html'); // remove dummy file
        TemplarUnitTestCase::tearDown();
    }
    function testBasicTest() {
        $templar = new TemplarPHP();
        $templar->envFileRoot = getcwd() . '/';
        $response = $templar->prepareResponse('file_a');
        echo $response;
    }
}
*/




/**********************************************************************
 *
 *********************************************************************/
/*
class BlankTestClass extends TemplarUnitTestCase {
    function testNameGoesHere() {
        $value = 2 + 2;
        $this->assertTrue($value == 4);
    }
}
*/




/**********************************************************************
 *
 *********************************************************************/
/*
class TestOfEnvironmentDetection extends WebTestCase {
    function testHomepage() {
        $scheme = (getenv('HTTPS') == 'on') ? 'https' : 'http';
        $host = getenv('HTTP_HOST');
        $path = dirname(getenv('SCRIPT_NAME'));
        $url = $scheme . '://' . $host . $path . '/temp/index';

        $this->get($url);
        $this->assertText('test');
    }
}
*/



?>
